package net.sf.tomcatmanager;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.logging.Logger;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
/**
* This class represents the preferences window, which exposes all the
* adjustable application settings.
*
* @author Martin Edling Andersson, Leonard van Driel
*/
public class PreferencesView extends JFrame {
private static final long serialVersionUID = 1L;
private static final transient Logger logger = Logger.getLogger(PreferencesView.class.toString());
private static final int MIN_SLEEP_TIME = 1000;
/**
* The color used for indicating text fields with incorrect content.
*/
private static final Color attentionColor = Color.decode("0xFFAAAA");
// GUI components
private JLabel tomcatLocationPathLabel;
private JTextField tomcatLocationPathTextField;
private JButton tomcatLocationPathButton;
private JLabel tomcatLocationPathExplanationLabel;
private CaretListener tomcatLocationPathCaretListener;
private JLabel javaHomePathLabel;
private JTextField javaHomePathTextField;
private JButton javaHomePathButton;
private JLabel javaHomePathExplanationLabel;
private CaretListener javaHomePathCaretListener;
private JLabel logPathLabel;
private JTextField logPathTextField;
private JButton logPathButton;
private JLabel logPathExplanationLabel;
private CaretListener logPathCaretListener;
private JLabel sleepTimeLabel;
private JTextField sleepTimeTextField;
private JLabel sleepTimeExplanationLabel;
private JLabel sleepTimeErrorLabel;
private CaretListener sleepTimeCaretListener;
private JLabel timeoutTimeLabel;
private JTextField timeoutTimeTextField;
private JLabel timeoutTimeExplanationLabel;
private JLabel timeoutTimeErrorLabel;
private CaretListener timeoutTimeCaretListener;
private JButton resetAllButton;
// model-view-controller
private Controller controller;
/**
* Adapter for caret listening.
*/
private class CaretAdapter implements CaretListener {
public void caretUpdate(CaretEvent e) {
}
}
/**
* Constructs a preference view by setting up the GUI.
*/
public PreferencesView() {
logger.setLevel(TomcatManagerGui.DEFAULT_LOG_LEVEL);
initListeners();
initComponents();
initWindow();
}
/**
* Loads all preferences from the model.
*/
public void loadFromModel() {
Model model = controller.getModel();
tomcatLocationPathTextField.setText(model.getTomcatLocationPath());
tomcatLocationPathCaretListener.caretUpdate(null);
javaHomePathTextField.setText(model.getJavaHomePath());
javaHomePathCaretListener.caretUpdate(null);
logPathTextField.setText(model.getLogPath());
logPathCaretListener.caretUpdate(null);
sleepTimeTextField.setText("" + model.getSleepTime());
sleepTimeCaretListener.caretUpdate(null);
timeoutTimeTextField.setText("" + model.getTimeoutTime());
timeoutTimeCaretListener.caretUpdate(null);
}
/**
* Stores all preferences in the model.
*/
public void saveToModel() {
Model model = controller.getModel();
if (!checkTomcatLocationPathTextField()) {
showWarningForField("Tomcat installation folder");
}
model.setTomcatLocationPath(tomcatLocationPathTextField.getText());
if (!checkJavaHomePathTextField()) {
showWarningForField("Java installation folder");
}
model.setJavaHomePath(javaHomePathTextField.getText());
if (!checkLogPathTextField()) {
showWarningForField("Log folder");
}
model.setLogPath(logPathTextField.getText());
if (!checkSleepTimeTextField()) {
showWarningForField("Sleep time");
}
try {
model.setSleepTime(Integer.parseInt(sleepTimeTextField.getText()));
} catch (NumberFormatException e) {
}
if (!checkTimeoutTimeTextField()) {
showWarningForField("Time out time");
}
try {
model.setTimeoutTime(Integer.parseInt(timeoutTimeTextField.getText()));
} catch (NumberFormatException e) {
}
}
private void showWarningForField(String name) {
JOptionPane.showMessageDialog(this, name + " was not set properly, this might cause problems.", name
+ " not set properly", JOptionPane.WARNING_MESSAGE);
}
/**
* Saves the prefences and hides this preference view.
*/
private void doHide() {
saveToModel();
setVisible(false);
}
/**
* Set up the window.
*/
private void initWindow() {
setTitle(About.NAME + " Preferences");
pack();
setSize(600, getSize().height);
setResizable(false);
setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
doHide();
}
});
KeyStroke cmdWStroke = KeyStroke.getKeyStroke("meta W");
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(cmdWStroke, "HIDE");
KeyStroke escStroke = KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0);
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(escStroke, "HIDE");
getRootPane().getActionMap().put("HIDE", new AbstractAction() {
private static final long serialVersionUID = 1L;
public void actionPerformed(ActionEvent e) {
doHide();
}
});
}
private boolean checkTomcatLocationPathTextField() {
String catalinaScriptPath = tomcatLocationPathTextField.getText() + File.separator
+ controller.getModel().getCatalinaScriptFile();
File catalinaScriptFile = new File(catalinaScriptPath.replace(File.separator + File.separator, File.separator));
return catalinaScriptFile.exists();
}
private boolean checkJavaHomePathTextField() {
String javaExecutablePath = javaHomePathTextField.getText() + controller.getModel().getJavaExecutableFile();
File javaExecutableFile = new File(javaExecutablePath.replace(File.separator + File.separator, File.separator));
return javaExecutableFile.exists();
}
private boolean checkLogPathTextField() {
File logFile = new File(logPathTextField.getText());
return logFile.exists() && logFile.isDirectory();
}
private boolean checkSleepTimeTextField() {
try {
int sleepTime = Integer.parseInt(sleepTimeTextField.getText());
controller.getModel().setSleepTime(sleepTime);
return sleepTime >= MIN_SLEEP_TIME;
} catch (NumberFormatException ex) {
return false;
}
}
private boolean checkTimeoutTimeTextField() {
try {
int sleepTime = Integer.parseInt(sleepTimeTextField.getText());
int timeoutTime = Integer.parseInt(timeoutTimeTextField.getText());
controller.getModel().setTimeoutTime(timeoutTime);
return timeoutTime > sleepTime;
} catch (NumberFormatException ex) {
return false;
}
}
private void initListeners() {
tomcatLocationPathCaretListener = new CaretAdapter() {
@Override
public void caretUpdate(CaretEvent e) {
Color color = checkTomcatLocationPathTextField() ? Color.white : attentionColor;
tomcatLocationPathTextField.setBackground(color);
controller.getModel().setTomcatLocationPath(tomcatLocationPathTextField.getText());
}
};
javaHomePathCaretListener = new CaretAdapter() {
@Override
public void caretUpdate(CaretEvent e) {
Color color = checkJavaHomePathTextField() ? Color.white : attentionColor;
javaHomePathTextField.setBackground(color);
controller.getModel().setJavaHomePath(javaHomePathTextField.getText());
}
};
logPathCaretListener = new CaretAdapter() {
@Override
public void caretUpdate(CaretEvent e) {
Color color = checkLogPathTextField() ? Color.white : attentionColor;
logPathTextField.setBackground(color);
controller.getModel().setLogPath(logPathTextField.getText());
}
};
sleepTimeCaretListener = new CaretAdapter() {
@Override
public void caretUpdate(CaretEvent e) {
boolean timeoutTimeOk = checkTimeoutTimeTextField();
timeoutTimeTextField.setBackground(timeoutTimeOk ? Color.white : attentionColor);
timeoutTimeErrorLabel.setVisible(!timeoutTimeOk);
try {
controller.getModel().setTimeoutTime(Integer.parseInt(timeoutTimeErrorLabel.getText()));
} catch (NumberFormatException ex) {
}
boolean sleepTimeOk = checkSleepTimeTextField();
sleepTimeTextField.setBackground(sleepTimeOk ? Color.white : attentionColor);
sleepTimeErrorLabel.setVisible(!sleepTimeOk);
try {
controller.getModel().setSleepTime(Integer.parseInt(sleepTimeTextField.getText()));
} catch (NumberFormatException ex) {
}
}
};
timeoutTimeCaretListener = sleepTimeCaretListener;
}
/**
* Instantiate and link all GUI components.
*/
private void initComponents() {
JPanel contentPanel = new JPanel();
getContentPane().add(contentPanel);
contentPanel.setLayout(new GridBagLayout());
contentPanel.setBorder(new EmptyBorder(20, 20, 20, 20));
int currentGridY = 0;
// tomcat location path
tomcatLocationPathLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = currentGridY;
constraints.anchor = GridBagConstraints.EAST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 0.0;
contentPanel.add(tomcatLocationPathLabel, constraints);
}
tomcatLocationPathLabel.setHorizontalAlignment(SwingConstants.RIGHT);
tomcatLocationPathLabel.setText("Tomcat installation");
tomcatLocationPathTextField = new JTextField();
tomcatLocationPathButton = new JButton();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weightx = 1.0;
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(tomcatLocationPathTextField, BorderLayout.CENTER);
panel.add(tomcatLocationPathButton, BorderLayout.EAST);
contentPanel.add(panel, constraints);
}
tomcatLocationPathTextField.setHorizontalAlignment(JTextField.LEFT);
tomcatLocationPathTextField.addCaretListener(tomcatLocationPathCaretListener);
tomcatLocationPathButton.setText("Browse...");
tomcatLocationPathButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
FileDialog dialog = new FileDialog(PreferencesView.this, "Select Tomcat Folder", FileDialog.LOAD);
System.setProperty("apple.awt.fileDialogForDirectories", "true");
dialog.setVisible(true);
System.setProperty("apple.awt.fileDialogForDirectories", "false");
if (dialog.getDirectory() != null) {
tomcatLocationPathTextField.setText(dialog.getDirectory() + dialog.getFile());
}
}
});
tomcatLocationPathExplanationLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets.left = 5;
constraints.insets.bottom = 5;
contentPanel.add(tomcatLocationPathExplanationLabel, constraints);
}
tomcatLocationPathExplanationLabel.setFont(new Font("Lucida Grande", 0, 11));
tomcatLocationPathExplanationLabel.setText("The path to the Tomcat installation root folder");
// java home path
javaHomePathLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.EAST;
constraints.fill = GridBagConstraints.HORIZONTAL;
contentPanel.add(javaHomePathLabel, constraints);
}
javaHomePathLabel.setHorizontalAlignment(SwingConstants.RIGHT);
javaHomePathLabel.setText("Java installation");
javaHomePathTextField = new JTextField();
javaHomePathButton = new JButton();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(javaHomePathTextField, BorderLayout.CENTER);
panel.add(javaHomePathButton, BorderLayout.EAST);
contentPanel.add(panel, constraints);
}
javaHomePathTextField.setHorizontalAlignment(JTextField.LEFT);
javaHomePathTextField.addCaretListener(javaHomePathCaretListener);
javaHomePathButton.setText("Browse...");
javaHomePathButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
FileDialog dialog = new FileDialog(PreferencesView.this, "Select Java Folder", FileDialog.LOAD);
System.setProperty("apple.awt.fileDialogForDirectories", "true");
dialog.setVisible(true);
System.setProperty("apple.awt.fileDialogForDirectories", "false");
if (dialog.getDirectory() != null) {
javaHomePathTextField.setText(dialog.getDirectory() + dialog.getFile());
}
}
});
javaHomePathExplanationLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets.left = 5;
constraints.insets.bottom = 5;
contentPanel.add(javaHomePathExplanationLabel, constraints);
}
javaHomePathExplanationLabel.setFont(new Font("Lucida Grande", 0, 11));
javaHomePathExplanationLabel.setText("The path to the Java installation home folder");
// log path
logPathLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.EAST;
constraints.fill = GridBagConstraints.HORIZONTAL;
contentPanel.add(logPathLabel, constraints);
}
logPathLabel.setHorizontalAlignment(SwingConstants.RIGHT);
logPathLabel.setText("Log folder");
logPathTextField = new JTextField();
logPathButton = new JButton();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(logPathTextField, BorderLayout.CENTER);
panel.add(logPathButton, BorderLayout.EAST);
contentPanel.add(panel, constraints);
}
logPathTextField.setHorizontalAlignment(JTextField.LEFT);
logPathTextField.addCaretListener(logPathCaretListener);
logPathButton.setText("Browse...");
logPathButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
FileDialog dialog = new FileDialog(PreferencesView.this, "Select Log Folder", FileDialog.LOAD);
System.setProperty("apple.awt.fileDialogForDirectories", "true");
dialog.setVisible(true);
System.setProperty("apple.awt.fileDialogForDirectories", "false");
if (dialog.getDirectory() != null) {
logPathTextField.setText(dialog.getDirectory() + dialog.getFile());
}
}
});
logPathExplanationLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets.left = 5;
constraints.insets.bottom = 5;
contentPanel.add(logPathExplanationLabel, constraints);
}
logPathExplanationLabel.setFont(new Font("Lucida Grande", 0, 11));
logPathExplanationLabel.setText("The path to the " + About.NAME + " logging folder");
// sleep time
sleepTimeLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.EAST;
constraints.fill = GridBagConstraints.HORIZONTAL;
contentPanel.add(sleepTimeLabel, constraints);
}
sleepTimeLabel.setHorizontalAlignment(SwingConstants.RIGHT);
sleepTimeLabel.setText("Sleep time");
sleepTimeTextField = new JTextField();
sleepTimeErrorLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(sleepTimeTextField, BorderLayout.WEST);
panel.add(sleepTimeErrorLabel, BorderLayout.CENTER);
contentPanel.add(panel, constraints);
}
sleepTimeTextField.setColumns(4);
sleepTimeTextField.setHorizontalAlignment(JTextField.LEFT);
sleepTimeTextField.addCaretListener(sleepTimeCaretListener);
sleepTimeErrorLabel.setText("Sleep time should be larger than 1000 and less than Time out time");
sleepTimeErrorLabel.setFont(new Font("Lucida Grande", 0, 11));
sleepTimeExplanationLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets.left = 5;
constraints.insets.bottom = 5;
contentPanel.add(sleepTimeExplanationLabel, constraints);
}
sleepTimeExplanationLabel.setFont(new Font("Lucida Grande", 0, 11));
sleepTimeExplanationLabel.setText("The millisecond interval between server status updates, e.g. 4000");
// server port
timeoutTimeLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 0;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.EAST;
constraints.fill = GridBagConstraints.HORIZONTAL;
contentPanel.add(timeoutTimeLabel, constraints);
}
timeoutTimeLabel.setHorizontalAlignment(SwingConstants.RIGHT);
timeoutTimeLabel.setText("Time out time");
timeoutTimeTextField = new JTextField();
timeoutTimeErrorLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(timeoutTimeTextField, BorderLayout.WEST);
panel.add(timeoutTimeErrorLabel, BorderLayout.CENTER);
contentPanel.add(panel, constraints);
}
timeoutTimeTextField.setColumns(4);
timeoutTimeTextField.setHorizontalAlignment(JTextField.LEFT);
timeoutTimeTextField.addCaretListener(timeoutTimeCaretListener);
timeoutTimeErrorLabel.setText("Time out time should be larger than Sleep time");
timeoutTimeErrorLabel.setFont(new Font("Lucida Grande", 0, 11));
timeoutTimeExplanationLabel = new JLabel();
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets.left = 5;
constraints.insets.bottom = 5;
contentPanel.add(timeoutTimeExplanationLabel, constraints);
}
timeoutTimeExplanationLabel.setFont(new Font("Lucida Grande", 0, 11));
timeoutTimeExplanationLabel.setText("The millisecond time out for operations on the server, e.g. 10000");
// Button for resetting all preferences
resetAllButton = new JButton("Reset all preferences..");
{
GridBagConstraints constraints = new GridBagConstraints();
constraints.gridx = 1;
constraints.gridy = ++currentGridY;
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.insets.top = 20;
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add(resetAllButton, BorderLayout.EAST);
contentPanel.add(panel, constraints);
}
resetAllButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// show warning dialog
int result = JOptionPane.showConfirmDialog(PreferencesView.this,
"This operation will reset all preferences.", "Reset all preferences",
JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
if (result == JOptionPane.OK_OPTION) {
controller.resetAllPreferences();
loadFromModel();
}
}
});
}
public void postInit() {
loadFromModel();
}
public void setController(Controller controller) {
this.controller = controller;
}
}